home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / mus / edit / AlgoRhythms.lha / AlgoRhythms / Source / files.c < prev    next >
C/C++ Source or Header  |  1994-11-25  |  15KB  |  487 lines

  1. /* Files.c
  2.     Copyright (c) 1990,1991,1992,1993 by Thomas E. Janzen
  3.     All Rights Reserved
  4.  
  5.     THIS SOFTWARE IS FURNISHED FREE OF CHARGE FOR STUDY AND USE AND MAY
  6.     BE COPIED ONLY FOR PERSONAL USE OR COMPLETELY AS OFFERED WITH NO
  7.     CHANGES FOR FREE DISTRIBUTION.  NO TITLE TO AND OWNERSHIP OF THE
  8.     SOFTWARE IS HEREBY TRANSFERRED.  THOMAS E. JANZEN ASSUMES NO 
  9.     RESPONSIBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE.
  10.     
  11.     Thomas E. Janzen
  12.     208A Olde Derby Road
  13.     Norwood, MA  02062-1761
  14.     (617)769-7733
  15.  
  16. **  FACILITY:
  17. **
  18. **    AlgoRhythms music improviser on Commodore (TM) Amiga (TM)
  19. **    compiled with SAS/C Amiga Compiler 6.50 
  20. **
  21. **  ABSTRACT:
  22. **
  23. **    Files.c handles file reading and writing.
  24. **
  25. **  AUTHORS: Thomas E. Janzen
  26. **
  27. **  CREATION DATE:    26-MAR-1990
  28. **
  29. **  MODIFICATION HISTORY:
  30. **    DATE    NAME    DESCRIPTION
  31. **  4 Jan 92 TEJ  last changes for 2.0
  32. **  1 JAN 93 TEJ  Changes for V3.0 ; add audio orchestra
  33. **--
  34. */
  35.  
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <math.h>
  40. #include <intuition/intuition.h>
  41. #include <devices/timer.h>
  42. #include "AlgoRhythms.h"    /* header for main function */
  43. #include "Window.h"        /* header for Window module */
  44. #include "Files.h"
  45. #include "audio.h"
  46.  
  47. #define BUFLEN 128
  48.  
  49. static int open_read_file (char *file_name);
  50. static int open_save_file (char *file_name);
  51.  
  52. FILE *file_ptr;    /* pointer to file  */
  53.  
  54. int save_file(char *file_name,    /* name of the file                   */
  55.     const struct timeval *total_duration, /* piece's duration           */
  56.     const int *scale_len,         /* num of notes in scale              */
  57.     const int *scale,             /* musical scale                      */
  58.     const int *voices,            /* number of voices                   */
  59.     const int *tempo,              /* pulses/second                      */
  60.     const FORM_TYPE *form,
  61.     const NOTE_EVENT_TYPE *events, /* List of note events        */
  62.     const NOTE_LEN_TYPE *note_len) /* min & max note length    */
  63. /*
  64. ** FUNCTIONAL DESCRIPTION:
  65. **  Saves a Form File.
  66. **
  67. ** RETURN VALUE:
  68. **      description: 0 if success; 1 if failed.
  69. **        data_type: int
  70. **
  71. ** ARGUMENTS:
  72. **
  73. **  file_name-
  74. **         description: name of the form file to write
  75. **           data_type: pointer to char 
  76. **              access: read only
  77. **
  78. **  total_duration-
  79. **         description: length of form to write to form file
  80. **           data_type: pointer to struct timeval
  81. **              access: read only
  82. **
  83. **  scale_len-
  84. **         description: number of pitches in scale
  85. **           data_type: pointer to int
  86. **              access: read only
  87. **
  88. **  scale-
  89. **         description: the scale in MIDI numbers
  90. **           data_type: pointer to int
  91. **              access: read only
  92. **
  93. **  voices-
  94. **         description: maximum number of voices to play
  95. **           data_type: pointer to int
  96. **              access: read only
  97. **
  98. **  tempo-
  99. **         description: pulse per second
  100. **           data_type: pointer to int
  101. **              access: read only
  102. **
  103. **  form-
  104. **         description: period/phase of mean/range
  105. **           data_type: pointer to FORM_TYPE
  106. **              access: read only
  107. **
  108. **
  109. **  note_len-
  110. **         description: durations of note in milliseconds
  111. **           data_type: NOTE_LEN_TYPE
  112. **              access: read only
  113. **
  114. ** DESIGN:
  115. **
  116. **  ROUTINE save_file
  117. **  : sts = open_save_file(file_name)
  118. **  : IF sts
  119. **  : : return sts
  120. **  : ENDIF
  121. **  : write duration
  122. **  : write min note len
  123. **  : write max note len
  124. **  : write scale length
  125. **  : write scale MIDI pitches
  126. **  : write number of voices
  127. **  : write tempo
  128. **  : write mean period & phase; range period & phase for pitch, duration, 
  129. **     and dynamic
  130. **  : write range period and phase for thickness
  131. **  : write channel parameters, one per line
  132. **  : close file
  133. **  ENDROUTINE
  134. */
  135. {
  136.     auto int sts = 0;               /* return status            */
  137.     register int    scale_index,    /* Index into the scale     */
  138.                     index;          /* general purpose index    */
  139.     
  140.     sts = open_save_file(file_name); /* open the file        */
  141.     if (sts) 
  142.     {
  143.         return sts;    /* if file opened, read it in    */
  144.     }
  145.     fprintf(file_ptr, "%4.2f\n", (double)total_duration->tv_secs);
  146.     fprintf(file_ptr, "%4.2f\n", ((double)note_len->len_i_min) / 1000.0);
  147.     fprintf(file_ptr, "%4.2f\n", ((double)note_len->len_i_max) / 1000.0);
  148.     fprintf(file_ptr, "%d\n", *scale_len);    /* len of scale */
  149.     for (scale_index = 0; scale_index < *scale_len; scale_index++)
  150.     {    
  151.         /* 
  152.         ** read in the whole scale 
  153.         */
  154.         fprintf(file_ptr, "%d\n", scale[scale_index]);
  155.     }
  156.     fprintf(file_ptr, "%d\n", *voices);    /* read number of voices */
  157.     fprintf(file_ptr, "%d\n", *tempo);     /* pulses per second */
  158.  
  159.     fprintf(file_ptr, "%4.2f\n", form->frm_s_pitch.prm_d_mean_cycle);
  160.     fprintf(file_ptr, "%4.2f\n", form->frm_s_pitch.prm_d_mean_phase);
  161.     fprintf(file_ptr, "%4.2f\n", form->frm_s_pitch.prm_d_range_cycle);
  162.     fprintf(file_ptr, "%4.2f\n", form->frm_s_pitch.prm_d_range_phase);
  163.     /*
  164.     ** RhythmForm
  165.     */
  166.     fprintf(file_ptr, "%4.2f\n", form->frm_s_rhythm.prm_d_mean_cycle);
  167.     fprintf(file_ptr, "%4.2f\n", form->frm_s_rhythm.prm_d_mean_phase);
  168.     fprintf(file_ptr, "%4.2f\n", form->frm_s_rhythm.prm_d_range_cycle);
  169.     fprintf(file_ptr, "%4.2f\n", form->frm_s_rhythm.prm_d_range_phase);
  170.     /*
  171.     **Dynamics Form
  172.     */
  173.     fprintf(file_ptr, "%4.2f\n", form->frm_s_dynamic.prm_d_mean_cycle);
  174.     fprintf(file_ptr, "%4.2f\n", form->frm_s_dynamic.prm_d_mean_phase);
  175.     fprintf(file_ptr, "%4.2f\n", form->frm_s_dynamic.prm_d_range_cycle);
  176.     fprintf(file_ptr, "%4.2f\n", form->frm_s_dynamic.prm_d_range_phase);
  177.     /*
  178.     ** Thickness Form 
  179.     */
  180.     fprintf(file_ptr, "%4.2f\n", form->frm_s_texture.prm_d_range_cycle);
  181.     fprintf(file_ptr, "%4.2f\n", form->frm_s_texture.prm_d_range_phase);
  182.     /* 
  183.     ** Read in MAXVOICE Event struct array parameters:
  184.     ** The lowest pitch,  the highest pitch,  the MIDI channel, whether
  185.     ** the voice is walking or random pitch 
  186.     */
  187.     for (index = 0; index < MAXVOICE; index++)
  188.     {
  189.         fprintf(file_ptr, "%d  %d  %d  %d %d\n",
  190.             events[index].nv_i_low_pitch, events[index].nv_i_high_pitch, 
  191.             events[index].nv_i_channel, events[index].nv_i_walking,
  192.             events[index].nv_i_audio);
  193.     }
  194.     fprint_orch(file_ptr);
  195.     fclose(file_ptr);
  196.     return 0;
  197. }
  198.  
  199. int read_file(char *file_name,      /* File Name char array             */
  200.     struct timeval *total_duration, /* total piece duration             */
  201.     int *scale_len,                 /* length of scale                  */
  202.     int *scale,                     /* musical scale array              */
  203.     int *voices,                    /* number of voices (<MAXVOICE)     */
  204.     int *tempo,                     /* ptr to pulses per second         */
  205.     FORM_TYPE *form,
  206.     NOTE_EVENT_TYPE *events,        /* ptr to array of events           */
  207.     NOTE_LEN_TYPE *note_len)
  208. /*
  209. ** FUNCTIONAL DESCRIPTION:
  210. **  Reads a Form File.
  211. **
  212. ** RETURN VALUE:
  213. **      description: 0 if success; 1 if failed.
  214. **        data_type: int
  215. **
  216. ** ARGUMENTS:
  217. **
  218. **  file_name-
  219. **         description: name of the form file to write
  220. **           data_type: pointer to char 
  221. **              access: write only
  222. **
  223. **  total_duration-
  224. **         description: length of form to write to form file
  225. **           data_type: pointer to struct timeval
  226. **              access: write only
  227. **
  228. **  scale_len-
  229. **         description: number of pitches in scale
  230. **           data_type: pointer to int
  231. **              access: write only
  232. **
  233. **  scale-
  234. **         description: the scale in MIDI numbers
  235. **           data_type: pointer to int
  236. **              access: write only
  237. **
  238. **  voices-
  239. **         description: maximum number of voices to play
  240. **           data_type: pointer to int
  241. **              access: write only
  242. **
  243. **  tempo-
  244. **         description: pulse per second
  245. **           data_type: pointer to int
  246. **              access: write only
  247. **
  248. **  form-
  249. **         description: period/phase of mean/range for pitch/rhyt/dyn/text
  250. **           data_type: pointer to FORM_TYPE
  251. **              access: write only
  252. **
  253. **  note_len-
  254. **         description: durations of a note in milliseconds
  255. **           data_type: NOTE_LEN_TYPE
  256. **              access: write only
  257. **
  258. ** ROUTINE
  259. **  : sts = open_read_file(file_name)
  260. **  : IF sts
  261. **  : : return sts
  262. **  : ENDIF
  263. **  : read duration
  264. **  : read min note len
  265. **  : read max note len
  266. **  : read scale length
  267. **  : read scale MIDI pitches
  268. **  : read number of voices
  269. **  : read tempo
  270. **  : read mean period & phase; range period & phase for pitch, duration, 
  271. **     and dynamic
  272. **  : read range period and phase for thickness
  273. **  : read channel parameters, one per line
  274. **  : close file
  275. ** ENDROUTINE
  276. */
  277. {
  278.     auto int sts = 0;               /* sts returned by some functions   */
  279.     auto int    scale_index,    /* Index into the scale             */
  280.                 index,          /* general purpose counter          */
  281.                 scan_qty,
  282.                 chair;
  283.     static char tempstring[BUFLEN], /* temporary string                 */
  284.                 instrument[BUFLEN];
  285.     auto char *str_ptr;             /* pointer to the temp string       */
  286.     auto double temp_time,
  287.                 min_len,
  288.                 max_len;
  289.     
  290.     sts = open_read_file(file_name);
  291.     if (sts)
  292.     {
  293.         return sts;
  294.     }
  295.     str_ptr = fgets(tempstring, BUFLEN, file_ptr); /* get duration */
  296.     temp_time = strtod(tempstring, (char **)NULL);
  297.     total_duration->tv_secs = (int)temp_time;
  298.     total_duration->tv_micro = 0L;
  299.         
  300.     str_ptr = fgets(tempstring, BUFLEN, file_ptr); /* min note len */
  301.     min_len = strtod(tempstring, (char **)NULL);
  302.     note_len->len_i_min = (int)(min_len * 1000.0);
  303.  
  304.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  305.     max_len = strtod(tempstring, (char **)NULL);
  306.     note_len->len_i_max = (int)(max_len * 1000.0); /* max note length */
  307.     note_len->len_i_dif = note_len->len_i_max - note_len->len_i_min;
  308.     scan_qty = fscanf(file_ptr, "%d", scale_len);    /* get scale length */
  309.     if (scan_qty != 1)
  310.     {
  311.         *scale_len = 0;
  312.     }
  313.     for (scale_index = 0; scale_index < (*scale_len); scale_index++)
  314.     {    
  315.         /* read in the whole scale (<120 notes ) */
  316.         fscanf(file_ptr, "%d", &scale[scale_index]);
  317.     }
  318.     scan_qty = fscanf(file_ptr, "%d", voices);  /* get num of voices */
  319.     if (scan_qty != 1)
  320.     {
  321.         *voices = 1;
  322.     }
  323.     scan_qty = fscanf(file_ptr, "%d", tempo);    /* get pulse/second */
  324.     if (scan_qty != 1)
  325.     {
  326.         *tempo = 1;
  327.     }
  328.     str_ptr = fgets(tempstring, BUFLEN, file_ptr); /* read end of line */
  329.  
  330.     /* Get the form structure parameter values */
  331.     /* 
  332.     **Pitch Form 
  333.     */
  334.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  335.     form->frm_s_pitch.prm_d_mean_cycle = strtod(tempstring, (char **)NULL);
  336.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  337.     form->frm_s_pitch.prm_d_mean_phase = strtod(tempstring, (char **)NULL);
  338.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  339.     form->frm_s_pitch.prm_d_range_cycle 
  340.       = strtod(tempstring, (char **)NULL);
  341.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  342.     form->frm_s_pitch.prm_d_range_phase 
  343.       = strtod(tempstring, (char **)NULL);
  344.     /* 
  345.     ** Rhythm Form 
  346.     */
  347.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  348.     form->frm_s_rhythm.prm_d_mean_cycle 
  349.       = strtod(tempstring, (char **)NULL);
  350.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  351.     form->frm_s_rhythm.prm_d_mean_phase 
  352.       = strtod(tempstring, (char **)NULL);
  353.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  354.     form->frm_s_rhythm.prm_d_range_cycle 
  355.       = strtod(tempstring, (char **)NULL);
  356.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  357.     form->frm_s_rhythm.prm_d_range_phase 
  358.       = strtod(tempstring, (char **)NULL);
  359.     /* 
  360.     **Dynamics Form 
  361.     */
  362.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  363.     form->frm_s_dynamic.prm_d_mean_cycle 
  364.       = strtod(tempstring, (char **)NULL);
  365.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  366.     form->frm_s_dynamic.prm_d_mean_phase 
  367.       = strtod(tempstring, (char **)NULL);
  368.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  369.     form->frm_s_dynamic.prm_d_range_cycle 
  370.       = strtod(tempstring, (char **)NULL);
  371.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  372.     form->frm_s_dynamic.prm_d_range_phase 
  373.       = strtod(tempstring, (char **)NULL);
  374.     /* 
  375.     ** Texture Form 
  376.     */
  377.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  378.     form->frm_s_texture.prm_d_range_cycle 
  379.       = strtod(tempstring, (char **)NULL);
  380.     str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  381.     form->frm_s_texture.prm_d_range_phase 
  382.       = strtod(tempstring, (char **)NULL);
  383.     /* 
  384.     ** get per-note values for lowest note,  highest note,  MIDI
  385.     ** channel, and whether it's a walking voice 
  386.     */
  387.     for (index = 0; index < MAXVOICE; index++)
  388.     {
  389.         str_ptr = fgets(tempstring, BUFLEN, file_ptr);
  390.         if (NULL == str_ptr)
  391.         {
  392.             break;
  393.         }
  394.         scan_qty = sscanf(str_ptr, "%d  %d  %d  %d  %d", 
  395.         &(events[index].nv_i_low_pitch), &(events[index].nv_i_high_pitch), 
  396.         &(events[index].nv_i_channel), &(events[index].nv_i_walking), 
  397.         &(events[index].nv_i_audio));
  398.         if (4 == scan_qty)
  399.         {
  400.            events[index].nv_i_audio = FALSE;
  401.         }
  402.     }
  403.     for (index; index < MAXVOICE; index++)
  404.     {
  405.         events[index].nv_i_low_pitch = 12;
  406.         events[index].nv_i_high_pitch = 97;
  407.         events[index].nv_i_walking = FALSE;
  408.         events[index].nv_i_channel = 0;
  409.     }
  410.     while ((str_ptr = fgets(tempstring, BUFLEN, file_ptr)) != NULL)
  411.     {
  412.         if (strlen(tempstring) != 0)
  413.         {
  414.             scan_qty = sscanf(str_ptr, "%d %s", &chair, instrument);
  415.             if (2 == scan_qty)
  416.             {
  417.                 sts = read_8svx(instrument, chair);
  418.             }
  419.         }
  420.     }
  421.     fclose(file_ptr);
  422.     return 0;
  423. }
  424.  
  425. static int open_read_file (char *file_name) 
  426. /*
  427. ** FUNCTIONAL DESCRIPTION:
  428. **  Opens the form file for reading
  429. **
  430. ** RETURN VALUE:
  431. **      description: 0 if success
  432. **        data_type: 1 if failed
  433. **
  434. ** ARGUMENTS:
  435. **
  436. **  file_name-
  437. **         description: name of the form file to open for read
  438. **           data_type: pointer to char
  439. **              access: read only
  440. **
  441. ** DESIGN:
  442. **  ROUTINE open_read_file()
  443. **  : fopen(file_name)
  444. **  : if failed return 1
  445. **  : return 0
  446. **  ENDROUTINE
  447. */{
  448.     auto char *mode = "r";    /* read mode */
  449.     if (NULL == (file_ptr = fopen(file_name,  mode)))
  450.     {
  451.         return 1;
  452.     }
  453.     return 0;
  454. }
  455.  
  456. static int open_save_file (char *file_name) 
  457. /*
  458. ** FUNCTIONAL DESCRIPTION:
  459. **  Opens the form file for writing
  460. **
  461. ** RETURN VALUE:
  462. **      description: 0 if success
  463. **        data_type: 1 if failed
  464. **
  465. ** ARGUMENTS:
  466. **
  467. **  file_name-
  468. **         description: name of the form file to open for write
  469. **           data_type: pointer to char
  470. **              access: read only
  471. **
  472. **  ROUTINE open_save_file()
  473. **  : fopen(file_name)
  474. **  : if failed return 1
  475. **  : return 0
  476. **  ENDROUTINE
  477. */
  478. {
  479.     auto char *mode = "w";    /* write mode */
  480.  
  481.     if (NULL == (file_ptr = fopen(file_name, mode)))
  482.     {
  483.         return 1;
  484.     }
  485.     return 0;
  486. }
  487.